package net.elive.utils;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

import net.elive.common.p2pnet.message.TimeSynMessage;
import net.elive.common.p2pnet.message.TimeSynMessageBack;
import net.elive.tools.MessageCheck;
import net.elive.tools.MessageType;

/**
 * 虚拟时间
 * @author jincool.cao@gmail.com
 *
 */
public class VTime implements Runnable {
	/**
	 * 主线程
	 */
	private Thread mainThread = null;
	/**
	 * 同步服务器时间线程
	 */
	private Thread synTimeThread = null;
	/**
	 * 服务器Ip地址
	 */
	private InetAddress ip;
	/**
	 * 服务器端口
	 */
	private int port;
	/**
	 * 现在时间
	 */
	private long nowTime = System.currentTimeMillis();
	
	public VTime(InetAddress ip,int port){
		this.ip = ip;
		this.port = port;
		mainThread  = new Thread(this);
		mainThread.start();
		synTimeThread  = new Thread(){
			public void run(){
				while(true){
					synchronizeNow();
					try {
						Thread.sleep(1000*60*60*12);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		};
	}
	@Override
	public void run() {
		while(true){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
				continue;
			}
			nowTime += 1000;
		}
	}
	/**
	 * 同步
	 */
	public void synchronizeNow(){
		new Thread(){
			public void run(){
				DatagramSocket ds = null;
				try {
					ds = new DatagramSocket();
					ds.setSoTimeout(3000);
				} catch (SocketException e) {
					e.printStackTrace();
					return ;
				}
				byte[] data = new byte[1024];
				DatagramPacket dp  = new DatagramPacket(data,data.length);
				TimeSynMessage tsm = new TimeSynMessage();
				tsm.setDestnationAddress(ip);
				tsm.setDestnationPort(port);
				for(int i=0;i<3;i++){
					i++;
					try {
						ds.send(tsm.getDatagramPacket());
						ds.receive(dp);
						if(MessageCheck.checkSType(dp) == MessageType.STYPE_TIME_SYN_MESSAGE_BACK){
							TimeSynMessageBack tsmb = new TimeSynMessageBack(dp);
							nowTime = tsmb.getNowTime();
							mainThread.interrupt();
							return ;
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
					
				}
				
			}
		};
	}
	
	
	public long getNowTime() {
		return nowTime;
	}
	/**
	 * 获取当前时间
	 * @return
	 */
	public long getCurrentTime(){
		return nowTime;
	}
	
}
